package edu.hawaii.wattwaiter.wattdepotcommands;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;

/**
 * Tests the ChartDataCollector to ensure that
 * it is working properly.
 * 
 * @author David Mau
 */
public class TestChartDataCollector {
  // Variables for repeated use.
  private String sameSizeCheck = "Checking that results and known data have same size Lists.";
  private String oahuGrid = "SIM_OAHU_GRID";
  private String aes = "SIM_AES";
  private String carbon = "carbon";
  private String energy = "energy";
  private String hour = "hour";
  
  /**
   * Tests normal operation of the ChartDataCollector.
   */
  @Test
  public void testChartDataCollector() {
    // Create a new ChartDataCollector object.
    ChartDataCollector test = new ChartDataCollector( null );
    // Turn on console debug mode.
    //test.debugModeOn();
    // Test to see if the default server was used.
    assertSame( "Testing to see if the default client was used.", test.client.getWattDepotUri(),
        test.defaultServer );
    
    // Go through the allZero list to see if all of the entries are 0.0.
    for ( Double entry : test.allZeroList ) {
      assertEquals( "Checking item in the allZeroList.", 0.0, entry, 0);
    }
    
    // Try to use another server.
    test = new ChartDataCollector("http://www.google.com/");
    // Turn on console debug mode.
    //test.debugModeOn();
    // Test to see if the specified server was used.
    assertSame( "Testing to see if the given client was used.", test.client.getWattDepotUri(),
        "http://www.google.com/" );
  }
  
  /**
   * Test normal operation of the getChartData method.
   */
  @Test
  public void testGetChartData() {
    // Create a new ChartDataCollector object.
    ChartDataCollector test = new ChartDataCollector( null );
    // Turn on console debug mode.
    //test.debugModeOn();
    // Get the results from the Class.
    List<Double> results = test.getChartData( carbon, "2009-10-25", 
        "2009-10-26", oahuGrid, hour );
    
    // Ready a List of known results.
    List<Double> known = new ArrayList<Double>();
    known.add( 802164.0 );
    known.add( 798676.0 );
    known.add( 796932.0 );
    known.add( 798676.0 );
    known.add( 801292.0 );
    known.add( 823092.0 );
    known.add( 860588.0 );
    known.add( 894596.0 );
    known.add( 928604.0 );
    known.add( 967844.0 );
    known.add( 1000567.0 );
    known.add( 1039425.0 );
    known.add( 1077875.0 );
    known.add( 1093650.0 );
    known.add( 1090950.0 );
    known.add( 1086450.0 );
    known.add( 1087350.0 );
    known.add( 1087350.0 );
    known.add( 1084525.0 );
    known.add( 1076325.0 );
    known.add( 1030705.0 );
    known.add( 959996.0 );
    known.add( 892852.0 );
    known.add( 828324.0 );
    
    assertEquals( sameSizeCheck, 
        results.size(), known.size() );
    
    // Ensure that all of the items in the list match
    for ( int counter = 0; counter < known.size(); counter++ ) {
      assertEquals( "Checking carbon hour data.", 
          results.get( counter ), known.get( counter ), 0 );
    }
    
    // Get the results from the Class.
    results = test.getChartData( energy, "2009-11-15", 
        "2009-11-16", oahuGrid, hour );
    
    // Ready a List of known results.
    known = new ArrayList<Double>();
    known.add( 5.02E8 );
    known.add( 5.0E8 );
    known.add( 4.99E8 );
    known.add( 5.0E8 );
    known.add( 5.015E8 );
    known.add( 5.14E8 );
    known.add( 5.355E8 );
    known.add( 5.55E8 );
    known.add( 5.745E8 );
    known.add( 5.97E8 );
    known.add( 6.155E8 );
    known.add( 6.355E8 );
    known.add( 6.545E8 );
    known.add( 6.625E8 );
    known.add( 6.61E8 );
    known.add( 6.585E8 );
    known.add( 6.59E8 );
    known.add( 6.59E8 );
    known.add( 6.575E8 );
    known.add( 6.535E8 );
    known.add( 6.305E8 );
    known.add( 5.925E8 );
    known.add( 5.54E8 );
    known.add( 5.17E8 );
    
    assertEquals( sameSizeCheck, 
        results.size(), known.size() );
    
    // Ensure that all of the items in the list match
    for ( int counter = 0; counter < known.size(); counter++ ) {
      assertEquals( "Checking energy hour data.", 
          results.get( counter ), known.get( counter ), 0 );
    }
    
    // Get the results from the Class.
    results = test.getChartData( carbon, "2009-11-02", 
        "2009-11-12", oahuGrid, "day" );
    
    // Ready a List of known results.
    known = new ArrayList<Double>();
    known.add( 2.4565908E7 );
    known.add( 2.467037E7 );
    known.add( 2.9959472E7 );
    known.add( 2.9959472E7 );
    known.add( 2.985501E7 );
    known.add( 2.2908808E7 );
    known.add( 2.2908808E7 );
    known.add( 2.4565908E7 );
    known.add( 2.467037E7 );
    known.add( 2.985501E7 );
    
    assertEquals( sameSizeCheck, 
        results.size(), known.size() );
    
    // Ensure that all of the items in the list match
    for ( int counter = 0; counter < known.size(); counter++ ) {
      assertEquals( "Checking carbon day data.", 
          results.get( counter ), known.get( counter ), 0 );
    }
    
    // Get the results from the Class.
    results = test.getChartData( energy, "2009-11-02", 
        "2009-11-12", oahuGrid, "day" );
    
    // Ready a List of known results.
    known = new ArrayList<Double>();
    known.add( 1.4764E10 );
    known.add( 1.4764E10 );
    known.add( 1.4764E10 );
    known.add( 1.4764E10 );
    known.add( 1.4764E10 );
    known.add( 1.4089E10 );
    known.add( 1.4089E10 );
    known.add( 1.4764E10 );
    known.add( 1.4764E10 );
    known.add( 1.4764E10 );
    
    assertEquals( sameSizeCheck, 
        results.size(), known.size() );
    
    // Ensure that all of the items in the list match
    for ( int counter = 0; counter < known.size(); counter++ ) {
      assertEquals( "Checking energy day data.", 
          results.get( counter ), known.get( counter ), 0 );
    }
    
    // Get the results from the Class.
    results = test.getChartData( carbon, "2009-11-01", 
        "2009-12-01", oahuGrid, "week" );
    
    // Ready a List of known results.
    known = new ArrayList<Double>();
    known.add( 1.89699346E8 );
    known.add( 1.84514706E8 );
    known.add( 2.0006887E8 );
    known.add( 1.8493231E8 );
    known.add( 1.84410244E8 );
    
    assertEquals( sameSizeCheck, 
        results.size(), known.size() );
    
    // Ensure that all of the items in the list match
    for ( int counter = 0; counter < known.size(); counter++ ) {
      assertEquals( "Checking carbon week data.", 
          results.get( counter ), known.get( counter ), 0 );
    }
    
    // Get the results from the Class.
    results = test.getChartData( energy, "2009-11-01", 
        "2009-12-01", oahuGrid, "week" );
    
    // Ready a List of known results.
    known = new ArrayList<Double>();
    known.add( 1.01998E11 );
    known.add( 1.01998E11 );
    known.add( 1.01998E11 );
    known.add( 1.01998E11 );
    known.add( 1.01998E11 );
    
    assertEquals( sameSizeCheck, 
        results.size(), known.size() );
    
    // Ensure that all of the items in the list match
    for ( int counter = 0; counter < known.size(); counter++ ) {
      assertEquals( "Checking energy week data.", 
          results.get( counter ), known.get( counter ), 0 );
    }
    
  }
  
  /**
   * Test normal operation of the getAllSubSources method.
   */
  @Test
  public void testGetAllSubSources() {
    // Create a new ChartDataCollector object.
    ChartDataCollector test = new ChartDataCollector( null );
    // Get the results from the Class.
    List<String> results = test.getAllSubSources( oahuGrid );
    
    // Ready a List of known results.
    List<String> known = new ArrayList<String>();
    known.add( "SIM_KAHE_1" );
    known.add( "SIM_KAHE_2" );
    known.add( "SIM_KAHE_3" );
    known.add( "SIM_KAHE_4" );
    known.add( "SIM_KAHE_5" );
    known.add( "SIM_KAHE_6" );
    known.add( "SIM_KAHE_7" );
    known.add( "SIM_WAIAU_5" );
    known.add( "SIM_WAIAU_6" );
    known.add( "SIM_WAIAU_7" );
    known.add( "SIM_WAIAU_8" );
    known.add( "SIM_WAIAU_9" );
    known.add( "SIM_WAIAU_10" );
    known.add( "SIM_HONOLULU_8" );
    known.add( "SIM_HONOLULU_9" );
    known.add( aes );
    known.add( "SIM_HPOWER" );
    known.add( "SIM_KALAELOA" );
    known.add( oahuGrid );

    assertEquals( sameSizeCheck, 
        results.size(), known.size() );
    
    // Ensure that all of the items in the list match.
    for ( int counter = 0; counter < known.size(); counter++ ) {
      assertEquals( "Checking Oahu Grid's subsources.", 
          known.get(counter).compareTo( results.get(counter) ), 0 );
    }
    
    // Get the results from the Class.
    results = test.getAllSubSources( "SIM_IPP" );
    
    // Ready a List of known results.
    known = new ArrayList<String>();
    known.add( aes );
    known.add( "SIM_HPOWER" );
    known.add( "SIM_KALAELOA" );
    known.add( "SIM_IPP" );
    
    assertEquals( sameSizeCheck, 
        results.size(), known.size() );
    
    // Ensure that all of the items in the list match.
    for ( int counter = 0; counter < known.size(); counter++ ) {
      assertEquals( "Checking IPP's subsources.", 
          known.get(counter).compareTo( results.get(counter) ), 0 );
    }
    
    // Get the results from the Class.
    results = test.getAllSubSources( aes );
    
    assertEquals( sameSizeCheck, 
        results.size(), 1 );
    assertEquals( "Checking AES' single item list.", 
        results.get(0).compareTo( aes ), 0 );
  }
  
  /**
   * Tests correct response for null detection.
   */
  @Test
  public void testNullArgumentResponse() {
    // Create a new ChartDataCollector object.
    ChartDataCollector test = new ChartDataCollector( null );
    
    // Get the list of doubles from the Class.
    List<Double> results = test.getChartData( null, "2009-10-27", 
        "2009-10-28", oahuGrid, hour );
    assertEquals( "Checking for correct response for null carbon or energy argument.", 
        results, null );
    
    results = test.getChartData( carbon, null, "2009-10-29", oahuGrid, hour );
    assertEquals( "Checking for correct response for null start date argument.", 
        results, null );
    
    results = test.getChartData( energy, "2009-10-29", null, oahuGrid, hour );
    assertEquals( "Checking for correct response for null end date argument.", 
        results, null );
    
    results = test.getChartData( carbon, "2009-10-30", "2009-10-31", null, hour );
    assertEquals( "Checking for correct response for null source argument.", 
        results, null );
    
    results = test.getChartData( energy, "2009-11-01", "2009-11-02", oahuGrid, null );
    assertEquals( "Checking for correct response for null time frame argument.", 
        results, null );
    
    results = test.getChartData( null, null, null, null, null );
    assertEquals( "Checking for correct response for all arguments being null.", 
        results, null );
    
    // Get the list of sub-sources from the Class.
    List<String> stringResults = test.getAllSubSources( null );
    assertEquals( "Checking for correct response for collecting sub-sources from null.", 
        stringResults, null );
  }
  
  /**
   * Tests for correct handling of bad String arguments.
   */
  @Test
  public void testBadStringArguments() {
    // Create a new ChartDataCollector object.
    ChartDataCollector test = new ChartDataCollector( null );
    
    // Get the list of doubles from the Class.
    List<Double> results = test.getChartData( "hair", "2009-11-03", 
        "2009-11-04", oahuGrid, hour );
    assertEquals( "Checking for correct response for bad carbon or energy argument.", 
        results, null );
    
    results = test.getChartData( carbon, "2009-11-05", 
        "2009-11-06", oahuGrid, "time travel" );
    assertEquals( "Checking for correct response for bad time frame argument.", 
        results, null );
  }
  
  /**
   * Tests for correct handling of bad date Strings.
   */
  @Test
  public void testBadDateStringArguments() {
    // Create a new ChartDataCollector object.
    ChartDataCollector test = new ChartDataCollector( null );
    
    // Get the list of doubles from the Class.
    List<Double> results = test.getChartData( carbon, "Blah", 
        "2009-11-07", oahuGrid, hour );
    assertEquals( "Checking for correct response for bad start date.", 
        results, null );
    
    results = test.getChartData( energy, "TenLetters", 
        "2009-11-08", oahuGrid, hour );
    assertEquals( "Checking for correct response for bad start date with correct length.", 
        results, null );
    
    results = test.getChartData( carbon, "2009-11-09", 
        "foobar", oahuGrid, hour );
    assertEquals( "Checking for correct response for bad end date.", 
        results, null );
    
    results = test.getChartData( energy, "2009-11-10", 
        "The Broken", oahuGrid, hour );
    assertEquals( "Checking for correct response for bad end date with correct length.", 
        results, null );
    
    results = test.getChartData( carbon, "foo", "bar", oahuGrid, hour );
    assertEquals( "Checking for correct response for bad start and end date.", 
        results, null );
    
    results = test.getChartData( energy, "2009-11-11", 
        "2009-11-11", oahuGrid, hour );
    assertEquals( "Checking for correct response for equal dates.", 
        results, null );
    
    results = test.getChartData( energy, "2009-11-13", 
        "2009-11-12", oahuGrid, hour );
    assertEquals( "Checking for correct response for start date after end date.", 
        results, null );
    
    results = test.getChartData( carbon, "1900-01-01", 
        "1900-01-02", oahuGrid, hour );
    assertEquals( "Checking for correct response for ridiculous dates for carbon.", 
        results, null );
    
    results = test.getChartData( energy, "9000-01-01", 
        "9000-01-02", oahuGrid, hour );
    assertEquals( "Checking for correct response for ridiculous dates for energy.", 
        results, null );
  }
  
  /**
   * Test bad source detection and handling.
   */
  @Test
  public void testBadSourceHandling() {
    // Create a new ChartDataCollector object.
    ChartDataCollector test = new ChartDataCollector( null );
    
    // Get the list of doubles from the Class.
    List<Double> results = test.getChartData( carbon, "2009-11-14", 
        "2009-11-15", "MOON", hour );
    assertEquals( "Checking for correct response for bad source for carbon.", 
        results, null );
    
    results = test.getChartData( energy, "2009-11-16", 
        "2009-11-17", "JUPITER", hour );
    assertEquals( "Checking for correct response for bad source for energy.", 
        results, null );
    
    // Get the list of sub-sources from the Class.
    List<String> stringResults = test.getAllSubSources( "PLUTO" );
    assertEquals( "Checking for correct response for collecting sub-sources from a bad source.", 
        stringResults, null );
  }
  
  /**
   * Testing for correct response to using commands while connected to a
   * non-functional server.
   */
  @Test
  public void testBadServerResponse() {
    // Create a new ChartDataCollector object.
    ChartDataCollector test = new ChartDataCollector( "http://www.google.com/" );
    List<Double> results = test.getChartData( carbon, "2009-11-18", 
        "2009-11-19", oahuGrid, hour );
    assertEquals( "Checking for correct response for collecting results from a bad server.", 
        results, null );
    
    List<String> stringResults = test.getAllSubSources( oahuGrid );
    assertEquals( "Checking for correct response for collecting sub-sources from a bad server.", 
        stringResults, null );
  }
}
